
/**
 * AppleIIGo
 * Mac OS X Controller
 * (C) 2007-2008 by Marc S. Ressl (mressl@umich.edu)
 * Released under the GPL
 */

#import "SDL/SDL.h"

#import "SDLMain.h"
#import "Controller.h"
#import "sdlInterface.h"

Controller *controller;

@implementation Controller

- (id)init {
	controller = self;
	isLaunching = YES;
	isSheetOpen = NO;
	isColor = YES;
	isPaused = NO;
	isMuted = NO;
	
	NSBundle *thisBundle = [NSBundle bundleForClass:[self class]];
	NSString *resourcesPath = [thisBundle resourcePath];
	insertArgument((char *) [[@"-r" stringByAppendingString:resourcesPath] 
							 UTF8String], 1);
	
	/* To-do implement profile paths */
	NSString *profilePath = @"AppleIIcplus";
	insertArgument((char *) [[@"-p" stringByAppendingString:profilePath] 
							 UTF8String], 1);
	
	speechSynthesizer = [NSSpeechSynthesizer new];
	
	return self;
}

- (void)dealloc {
	[super dealloc];
}

- (void)terminate:(id)sender {
	SDL_Event event;
	event.type = SDL_QUIT;
	SDL_PushEvent(&event);
}

- (void)notifyAndOpenDisk:(NSString *)filename isAltDrive:(int)isAltDrive {
	[[NSDocumentController sharedDocumentController]
	 noteNewRecentDocumentURL:[NSURL fileURLWithPath:filename]];
	emulatorMount((char *) [filename UTF8String], 0);
}

- (void)showMountMessage:(int)messageIndex {
	/*	NSString *informativeText;
	 
	 if (isSheetOpen)
	 return;
	 
	 switch (messageIndex) {
	 case MOUNT_MSG_ALREADYMOUNTED:
	 informativeText = NSLocalizedString(
	 @"It is already mounted.",
	 @"It is already mounted.");
	 break;
	 case MOUNT_MSG_NOTMOUNTABLE:
	 informativeText = NSLocalizedString(
	 @"There is no appropriate disk drive.",
	 @"There is no appropriate disk drive.");
	 break;
	 case MOUNT_MSG_ACCESSERROR:
	 informativeText = NSLocalizedString(
	 @"AppleIIGo was unable to determine its type.",
	 @"AppleIIGo was unable to determine its type.");
	 break;
	 }
	 
	 isSheetOpen = YES;
	 NSBeginAlertSheet(NSLocalizedString(
	 @"The disk image could not be mounted.",
	 @"The disk image could not be mounted."),
	 nil, nil, nil,
	 [NSApp mainWindow], self,
	 @selector(showMountMessageDidEnd:returnCode:contextInfo:),
	 nil, nil, informativeText);*/
}

- (void)showMountMessageDidEnd:(NSWindow *)sheet returnCode:(int)returnCode
				   contextInfo:(void *)contextInfo {
	/*	[sheet close];
	 isSheetOpen = NO;*/
}

- (BOOL)application:(NSApplication *)theApplication 
		   openFile:(NSString *)filename {
	if (isLaunching) {
		[[NSDocumentController sharedDocumentController]
		 noteNewRecentDocumentURL:[NSURL fileURLWithPath:filename]];
		pushArgument((char *) [filename UTF8String]);
		return YES;
	}
	
	if (isSheetOpen) {
		NSBeep();
		return NO;
	}
	
	[self notifyAndOpenDisk:filename isAltDrive:FALSE];
	return YES;
}

- (IBAction)showPreferences:(id)sender {
}

- (IBAction)openDocument:(id)sender {
	NSArray *fileTypes = [NSArray arrayWithObjects:@"dsk", @"do", @"po", @"nib",
						  @"2mg", @"2img", @"hdv", @"fdi", nil];
	
	isSheetOpen = YES;
	NSOpenPanel *panel = [NSOpenPanel openPanel];
	[panel beginSheetForDirectory:nil 
							 file:nil 
							types:fileTypes
				   modalForWindow:[NSApp mainWindow] 
					modalDelegate:self
				   didEndSelector:@selector(openDocumentDidEnd:returnCode:
											contextInfo:)
					  contextInfo:(void *)0];
}

- (void)openDocumentDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode
			   contextInfo:(int)contextInfo {
	[sheet close];
	isSheetOpen = NO;
	
	if (returnCode == NSOKButton)
		[self notifyAndOpenDisk:[[sheet filenames] objectAtIndex:0]
					 isAltDrive:contextInfo];
}

- (BOOL)isPasteAvailable {
	NSPasteboard *pb = [NSPasteboard generalPasteboard];
	NSArray *pasteTypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
	NSString *bestType = [pb availableTypeFromArray:pasteTypes];
	return (bestType != nil);
}

- (IBAction)copy:(id)sender {
	char copyBuffer[EMULATOR_COPYBUFFER_SIZE];
	emulatorCopy(copyBuffer, sizeof(copyBuffer));
	
	NSPasteboard *pb = [NSPasteboard generalPasteboard];
	NSArray *types = [NSArray arrayWithObjects:NSStringPboardType, nil];
	[pb declareTypes:types owner:self];
	
	[pb setString:[NSString stringWithUTF8String:copyBuffer] 
		  forType:NSStringPboardType];
}

- (IBAction)paste:(id)sender {
	if ([self isPasteAvailable]) {
		NSPasteboard *pb = [NSPasteboard generalPasteboard];
		NSString *pasteString = [pb stringForType:NSStringPboardType];
		NSMutableString *fixedString = [NSMutableString 
										stringWithString:pasteString];
		/* Convert newlines */
		[fixedString replaceOccurrencesOfString:@"\n"
									 withString:@"\r"
										options:NSLiteralSearch
										  range:NSMakeRange(0, 
															[pasteString
															 length])];
		
		emulatorPaste((char *) [fixedString UTF8String]);
	}
}

- (IBAction)startSpeaking:(id)sender {
	char copyBuffer[EMULATOR_COPYBUFFER_SIZE];
	emulatorCopy(copyBuffer, sizeof(copyBuffer));
	
	[speechSynthesizer stopSpeaking];
	[speechSynthesizer startSpeakingString:[NSString 
											stringWithUTF8String:copyBuffer]];
}

- (IBAction)stopSpeaking:(id)sender {
	if ([speechSynthesizer isSpeaking])
		[speechSynthesizer stopSpeaking];
}

- (IBAction)setFullscreen:(id)sender {
	emulatorSetVideoFullscreen(true);
}

- (IBAction)clearLastCharacterSet:(id)sender {
	if (lastCharacterSetMenuItem)
		[lastCharacterSetMenuItem setState:NSOffState];
	lastCharacterSetMenuItem = sender;
}

- (IBAction)setCharacterSetDefault:(id)sender {
	[self clearLastCharacterSet:sender];
	[sender setState:NSOnState];
	emulatorSetVideoCharacterSet(EMULATOR_CHARACTERSET_DEFAULT);
}

- (IBAction)setCharacterSetDE:(id)sender {
	[self clearLastCharacterSet:sender];
	[sender setState:NSOnState];
	emulatorSetVideoCharacterSet(EMULATOR_CHARACTERSET_DE);
}

- (IBAction)setCharacterSetDK:(id)sender {
	[self clearLastCharacterSet:sender];
	[sender setState:NSOnState];
	emulatorSetVideoCharacterSet(EMULATOR_CHARACTERSET_DK);
}

- (IBAction)setCharacterSetES:(id)sender {
	[self clearLastCharacterSet:sender];
	[sender setState:NSOnState];
	emulatorSetVideoCharacterSet(EMULATOR_CHARACTERSET_ES);
}

- (IBAction)setCharacterSetFR:(id)sender {
	[self clearLastCharacterSet:sender];
	[sender setState:NSOnState];
	emulatorSetVideoCharacterSet(EMULATOR_CHARACTERSET_FR);
}

- (IBAction)setCharacterSetIT:(id)sender {
	[self clearLastCharacterSet:sender];
	[sender setState:NSOnState];
	emulatorSetVideoCharacterSet(EMULATOR_CHARACTERSET_IT);
}

- (IBAction)setCharacterSetSE:(id)sender {
	[self clearLastCharacterSet:sender];
	[sender setState:NSOnState];
	emulatorSetVideoCharacterSet(EMULATOR_CHARACTERSET_SE);
}

- (IBAction)setCharacterSetUK:(id)sender {
	[self clearLastCharacterSet:sender];
	[sender setState:NSOnState];
	emulatorSetVideoCharacterSet(EMULATOR_CHARACTERSET_UK);
}

- (IBAction)setCharacterSetUS:(id)sender {
	[self clearLastCharacterSet:sender];
	[sender setState:NSOnState];
	emulatorSetVideoCharacterSet(EMULATOR_CHARACTERSET_US);
}

- (IBAction)toggleMute:(id)sender {
	isMuted = !isMuted;
	if (isMuted)
		[sender setState:NSOnState];
	else
		[sender setState:NSOffState];
	emulatorSetAudioVolume(isMuted ? 0.0F : 1.0F);
}

- (IBAction)togglePause:(id)sender {
	isPaused = !isPaused;
	if (isPaused)
		[sender setState:NSOnState];
	else
		[sender setState:NSOffState];
	emulatorSetPause(isPaused);
}
- (IBAction)sendReset:(id)sender {
	emulatorSendReset();
}

- (IBAction)sendRestart:(id)sender {
	emulatorSendRestart();
}

- (IBAction)showHelp:(id)sender {
	NSURL *url = [NSURL URLWithString:@APPLEIIGO_ABOUTURL];
	[[NSWorkspace sharedWorkspace] openURL: url];
}

- (IBAction)checkForUpdates:(id)sender {
	NSURL *url = [NSURL	URLWithString:@APPLEIIGO_UPDATEURL];
	[[NSWorkspace sharedWorkspace] openURL: url];
}

- (IBAction)donate:(id)sender {
	NSURL *url = [NSURL	URLWithString:@APPLEIIGO_DONATEURL];
	[[NSWorkspace sharedWorkspace] openURL: url];
}

- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item {
	SEL action = [item action];
	if (action == @selector(copy:))
		return emulatorIsCopyAvailable() ? YES : NO;
	else if (action == @selector(paste:))
		return [self isPasteAvailable] ? YES : NO;
	else if (action == @selector(stopSpeaking:))
		return [speechSynthesizer isSpeaking] ? YES : NO;
	else if (action == @selector(openDocument:))
		return isSheetOpen ? NO : YES;
	
	return [super validateUserInterfaceItem:item];
}

-(void) applicationWillFinishLaunching:(NSNotification *)note {
	/* Update recents menu */
	NSMenu *mainmenu = [NSApp mainMenu];
	NSMenuItem *file = [mainmenu itemWithTitle:@"File"];
	NSMenu *menu = [file submenu];
	NSMenuItem *openRecent = [menu itemWithTitle:@"Open Recent"];
	NSMenu *openRecentMenu = [openRecent submenu];
	[openRecentMenu performSelector:@selector(_setMenuName:)
						 withObject:@"NSRecentDocumentsMenu"];
}

- (void) applicationDidFinishLaunching:(NSNotification *)note {
	int status;
	
	lastCharacterSetMenuItem = [[[[[[NSApp mainMenu] itemWithTitle:@"View"]
								   submenu] itemWithTitle:@"Text Encoding"]
								 submenu] itemWithTitle:@"Default"];
	
	[[[[[NSApp mainMenu] itemWithTitle:@"View"] submenu]
	  itemWithTitle:@"Color Display"] setState:NSOnState];
	
	isLaunching = NO;
	
	status = SDL_main(sdlArgC, sdlArgV);
	
	exit(status);
}

@end
